package com.apes.framework.plugin.event;


import java.util.*;

/**
 * 功能：AbstractEventMulticaster
 *
 * @author xul
 * @create 2018-02-02 11:41
 */
public abstract class AbstractEventMulticaster implements EventMulticaster {

    private Set<ApesEventListener> apesEventListeners = new HashSet<>();

    private static final Map<String, AbstractEventMulticaster.ListenerRegistry> cachedApesEventListeners = new HashMap();

    public void removeAllListeners() {
        apesEventListeners.clear();
    }

    public void addListener(ApesEventListener listener) {
        apesEventListeners.add(listener);
    }

    public void removeListener(ApesEventListener listener) {
        apesEventListeners.remove(listener);
    }

    private String topicWithType(String topic, String type) {
        return topic + "#" + type;
    }

    protected List<ApesEventListener> getApesEventListeners(ApesEvent event) {
        String topic = event.getTopic();
        if (!cachedApesEventListeners.containsKey(topic) || cachedApesEventListeners.get(topic).getApesEventListeners().isEmpty()) {
            cacheEventListeners(event);
        }
        return cachedApesEventListeners.get(topic).getApesEventListeners();
    }

    private void cacheEventListeners(ApesEvent event){
        String topic = event.getTopic();
        LinkedList<ApesEventListener> allListeners = new LinkedList();
        if (apesEventListeners != null && apesEventListeners.size() > 0) {
            for (ApesEventListener apesEventListener : apesEventListeners) {
                if (supportsEvent(apesEventListener, event)) {
                    allListeners.add(apesEventListener);
                }
            }
            sortApesEventListener(allListeners);
        }
        AbstractEventMulticaster.ListenerRegistry listenerRegistry = new AbstractEventMulticaster.ListenerRegistry(allListeners);
        cachedApesEventListeners.put(topic, listenerRegistry);
    }


    protected boolean supportsEvent(ApesEventListener listener, ApesEvent event) {
        return listener.getTopic().equalsIgnoreCase(event.getTopic());
    }

    protected void sortApesEventListener(List<ApesEventListener> ApesEventListeners) {
        Collections.sort(ApesEventListeners, (o1, o2) -> {
            if (o1.getOrder() > o2.getOrder()) {
                return 1;
            } else if (o1.getOrder() < o2.getOrder()) {
                return -1;
            } else {
                return 0;
            }
        });
    }

    private class ListenerRegistry {

        public List<ApesEventListener> ApesEventListeners;

        private ListenerRegistry(List<ApesEventListener> ApesEventListeners) {
            this.ApesEventListeners = ApesEventListeners;
        }

        public List<ApesEventListener> getApesEventListeners() {
            return ApesEventListeners;
        }
    }
}
